package by.home;


import by.home.exceptions.OutOfMapBordersException;
import by.home.exceptions.PlacingOnMapException;

public class TreasureFinder extends Point implements PositionInspector {

  private Point[][] treasureMap = null;
  private Treasure treasure = null;

  public TreasureFinder(int finderPositionX, int finderPositionY, Point[][] treasureMap) {
    super(finderPositionX, finderPositionY, false);
    this.treasureMap = treasureMap;
  }

  public boolean moveFinderUp() throws OutOfMapBordersException, PlacingOnMapException {
    if (isOnMap(this.getPositionX(), this.getPositionY() + 1)) {
      if (isEmptyPosition(this.getPositionX(), this.getPositionY() + 1)) {
        this.setPositionY(this.getPositionY() + 1);
        treasureMap[this.getPositionX()][this.getPositionY()] = this;
        treasureMap[this.getPositionX()][this.getPositionY() - 1] = new Sand(this.getPositionX(), this.getPositionY() - 1);
      } else {
        throw new PlacingOnMapException();
      }
    } else {
      throw new OutOfMapBordersException();
    }
    return false;
  }

  public boolean moveFinderDown() throws OutOfMapBordersException, PlacingOnMapException {
    if (isOnMap(this.getPositionX(), this.getPositionY() - 1)) {
      if (isEmptyPosition(this.getPositionX(), this.getPositionY() - 1)) {
        this.setPositionY(this.getPositionY() - 1);
        treasureMap[this.getPositionX()][this.getPositionY()] = this;
        treasureMap[this.getPositionX()][this.getPositionY() + 1] = new Sand(this.getPositionX(), this.getPositionY() + 1);
      } else {
        throw new PlacingOnMapException();
      }
    } else {
      throw new OutOfMapBordersException();
    }
    return false;
  }

  public boolean moveFinderLeft() throws OutOfMapBordersException, PlacingOnMapException {
    if (isOnMap(this.getPositionX() - 1, this.getPositionY())) {
      if (isEmptyPosition(this.getPositionX() - 1, this.getPositionY())) {
        this.setPositionX(this.getPositionX() - 1);
        treasureMap[this.getPositionX()][this.getPositionY()] = this;
        treasureMap[this.getPositionX() + 1][this.getPositionY()] = new Sand(this.getPositionX() + 1, this.getPositionY());
      } else {
        throw new PlacingOnMapException();
      }
    } else {
      throw new OutOfMapBordersException();
    }
    return false;
  }

  public boolean moveFinderRight() throws OutOfMapBordersException, PlacingOnMapException {
    if (isOnMap(this.getPositionX() + 1, this.getPositionY())) {
      if (isEmptyPosition(this.getPositionX() + 1, this.getPositionY())) {
        this.setPositionX(this.getPositionX() + 1);
        treasureMap[this.getPositionX()][this.getPositionY()] = this;
        treasureMap[this.getPositionX() - 1][this.getPositionY()] = new Sand(this.getPositionX() - 1, this.getPositionY());
      } else {
        throw new PlacingOnMapException();
      }
    } else {
      throw new OutOfMapBordersException();
    }
    return false;
  }

  @Override
  public boolean isEmptyPosition(int posX, int posY) {
    if (isTreasure(posX, posY)) {
      this.treasure = (Treasure) treasureMap[posX][posY];
    }
    return treasureMap[posX][posY].isPassable();
  }

  @Override
  public boolean isOnMap(int posX, int posY) {
    return posX < treasureMap.length && posY < treasureMap[1].length;
  }

  private boolean isTreasure(int posX, int posY) {
    return treasureMap[posX][posY].getClass().equals(Treasure.class);
  }

  public boolean hasFound() {
    return this.treasure != null;
  }
}
